package com.kgc.scd.controller;

import com.alibaba.fastjson.JSON;
import com.kgc.scd.annotation.RequestShopUser;
import com.kgc.scd.annotation.TokenPermission;
import com.kgc.scd.bean.ShopUser;
import com.kgc.scd.delay.OrderDelay;
import com.kgc.scd.service.*;
import com.kgc.scd.util.RedisUtils;
import com.kgc.scd.util.RequestResult;
import com.kgc.scd.util.ResultBuildUtil;
import com.kgc.scd.util.SnowUtil;
import com.kgc.scd.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created On : 2022/11/16.
 * <p>
 * Author : Administrator
 * <p>
 * Description: OrderService
 */

@Slf4j
@RestController
@Api(tags = "14、支付接口(tlx)",value = "下单成功后，用户通过扫描微信二维码支付，并生成订单号")
public class OrderController {


    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private BushGoodsService bushGoodsService;
    @Autowired
    private OrderService orderService;

    @Autowired
    private SnowUtil snowUtil;

    @Autowired
    private WechatPayWebService wechatPaywebService;

    @Autowired
    private CouponService couponService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private SeckillService seckillService;
    /**
     * Created On : 2022/11/16.
     * <p>
     * Author : tlx
     * <p>
     * Description: 商品下单
     */
    @GetMapping("/createOrder")
    @TokenPermission
    @ApiOperation(value = "从商品页面直接下单/生成订单", notes = "基于redis,统一返回,异步存储数据")
    @ApiResponses({
            @ApiResponse(code = 200,message = "成功"),
            @ApiResponse(code = 999,message = "失败")
    })
    public RequestResult<?> createOrder(@ApiIgnore @RequestShopUser ShopUser shopUser, String pid, String addressId, String content, Integer number) {

        log.info("参数:" + pid);
        log.info("参数:" + addressId);
        log.info("参数:" + content);
        log.info("参数:" + number);

        if (number < 0) {
            return ResultBuildUtil.fail("购买数量不能为负数");
        } else if (number > 50) {
            return ResultBuildUtil.fail("购买超过单次购买最大数额:50");
        }

        //获取用户地址信息,地址校验,判断该地址是否存在
        //todo 暂且不知前端需要相应信息
        ShopAddressVO shopAddressVO = orderService.involveShopAddressServerById(addressId);
        if (shopAddressVO == null) {
            return ResultBuildUtil.fail("地址编号不存在");
        }

        //获取所购买的商品信息 //todo 这边redis
        ShopGoodsVO shopGoodsVO = orderService.involveShopGoodsServerById(pid);
        //计算该订单的价格


        ShopOrderVO shopOrderVO = new ShopOrderVO();
        shopOrderVO.setId(snowUtil.snowId());
        shopOrderVO.setUserId(shopUser.getId());
        shopOrderVO.setAddressId(addressId);
        shopOrderVO.setShoppingStatus("未支付");
        shopOrderVO.setPostscript(content);
        //todo 运费待商议
        shopOrderVO.setShoppingFee(10.00);
        log.info("参数" + shopGoodsVO.getIsOnSale());
        log.info("参数" + shopGoodsVO.getSalePrice());
        log.info("参数" + shopGoodsVO.getRetailPrice());
        shopOrderVO.setAddTime(new Date());

        //todo 生成订单详情表,存入数据库,redis
        ShopOrderitemVO shopOrderitemVO = new ShopOrderitemVO();
        shopOrderitemVO.setId(snowUtil.snowId());
        shopOrderitemVO.setBuyingPrice(shopGoodsVO.getIsOnSale() == 1 ? shopGoodsVO.getSalePrice() * number : shopGoodsVO.getRetailPrice() * number);
        shopOrderitemVO.setUserId(shopUser.getId());
        shopOrderitemVO.setNumber(number);
        shopOrderitemVO.setGoodsId(shopGoodsVO.getId());
        shopOrderitemVO.setOrderId(shopOrderVO.getId());
        shopOrderitemVO.setGoodsName(shopGoodsVO.getName());
        shopOrderitemVO.setCategoryId(shopGoodsVO.getCategoryId());

        shopOrderVO.setOrderPrice(shopOrderitemVO.getBuyingPrice()+shopOrderVO.getShoppingFee());

        log.info("输入:" + shopOrderitemVO);
        //把订单详情放入订单中
        shopOrderVO.setShopOrderitemVO(shopOrderitemVO);
        //异步这边存入数据库
        orderService.involveShopOrderServer(shopOrderVO);
        orderService.involveSaveShopOrderitemServer(shopOrderitemVO);

        log.info("shopOrder:"+shopOrderVO);
        //存入redis缓存
        redisUtils.set(shopOrderVO.getId(), shopOrderVO);


        return ResultBuildUtil.success(shopOrderVO.getId());    }

    @PostMapping("/payOrder")
    @TokenPermission
    @ApiOperation(value = "生成预支付订单(点击商品详情进去之后,生成订单后的支付)", notes = "基于redis,统一返回,异步存储数据")
    @ApiResponses({
            @ApiResponse(code = 200,message = "成功"),
            @ApiResponse(code = 999,message = "失败")
    })
    public RequestResult<?> payOrder(@ApiIgnore @RequestShopUser ShopUser shopUser,String orderId,String couponId) throws Exception {



        log.info("参数:" + orderId);
        ShopOrderVO shopOrderVO = orderService.involveGetShopOrderById(orderId);
        if(shopOrderVO==null){
            return  ResultBuildUtil.fail("999","该订单号已经被取消/不存在");
        }
        log.info("shopOrderVo:"+shopOrderVO);

        //获取实际交付金额,这个从数据库取,(订单价格+运费)
        double orderPrice = shopOrderVO.getOrderPrice();


        Object shopOrderVOObj = redisUtils.get(orderId);
        if (shopOrderVOObj == null) {
            return ResultBuildUtil.fail("999","该订单不存在,请检查后再进行支付");
        }
        ShopOrderVO shopOrderVOr = JSON.parseObject(shopOrderVOObj.toString(), ShopOrderVO.class);
        ShopOrderitemVO shopOrderitemVO = shopOrderVOr.getShopOrderitemVO();

        //todo 获取优惠券id,判断是否可用,调用接口
        Map<String,Object> couponMap=couponService.wouldUseCoupons(couponId,shopOrderitemVO.getCategoryId(),orderPrice,shopUser.getId());
        if (couponMap.get("state").equals(false)){

            return ResultBuildUtil.fail(couponMap.get("condition"));
        }

        System.out.println(couponMap);
        //判断是否是会员填入实际购买价格,会员打8折
        double getActualPrice=(Double) couponMap.get("money");

        shopOrderVOr.setActualPrice(shopUser.isUserLevelId()?getActualPrice*0.8:getActualPrice);
        shopOrderVO.setActualPrice(shopUser.isUserLevelId()?getActualPrice*0.8:getActualPrice);

        orderService.involveUpdateShopOrderPrice(shopOrderVOr);
        redisUtils.set(shopOrderVO.getId(), shopOrderVOr);

        Map<String, String> msgMap = new HashMap<>();
        msgMap.put("orderId", shopOrderitemVO.getOrderId());
        msgMap.put("goodName", shopOrderitemVO.getGoodsName());

        log.info("msgMap:{}",msgMap);
        //开始进行微信支付
        //请求微信统一下单接口，下预支付订单，返回支付链接
        //todo 这边orderPrice要换成couponMap.get("money")
        Map<String, Object> returnMap = wechatPaywebService.wechatPayUnifyOrder(1, msgMap);

        OrderDelay orderDelay=new OrderDelay(orderId,60000);
        taskService.addTask(orderDelay);
        log.info(orderId+"在"+ LocalDateTime.now() +"加入了延时任务");
        return ResultBuildUtil.success(returnMap);
    }


    @GetMapping("/createSeckillOrder")
    @TokenPermission
    @ApiOperation(value = "秒杀抢购", notes = "基于redis,统一返回,异步存储数据")
    public RequestResult<?> createskillOrder(@ApiIgnore @RequestShopUser ShopUser shopUser, String pid,String content,String addressId,Integer number){

        if (number < 0) {
            return ResultBuildUtil.fail("购买数量不能为负数");
        } else if (number > 50) {
            return ResultBuildUtil.fail("购买超过单次购买最大数额:50");
        }


        //获取用户地址信息,地址校验,判断该地址是否存在
        //todo 暂且不知前端需要相应信息
        ShopAddressVO shopAddressVO = orderService.involveShopAddressServerById(addressId);
        if (shopAddressVO == null) {
            return ResultBuildUtil.fail("地址编号不存在");
        }
        //判断商品是否是抢购商品
        ShopGoodsVO shopGoodsVO=bushGoodsService.involveServerGoodsIsBush(pid);
        log.info("发布时间:"+shopGoodsVO.getBushStartTime());
        log.info("现在时间:"+(new Date()));
        if(shopGoodsVO==null||shopGoodsVO.getBushStartTime().getTime()<(new Date()).getTime()){
            return ResultBuildUtil.fail("该商品不在抢购中");
        }

        //进行去判断人数
        if (seckillService.checkBuyUserCount(pid)){

            return ResultBuildUtil.fail("抢购失败,当前抢购人数过多");
        }

        //判断商品库存是否足够
        if (!orderService.involveJudgeGoodsNumberEnough(pid,number)){

            return ResultBuildUtil.fail("抢购失败，商品库存不足");
        }
        //判断是否已经抢购
        if (seckillService.checkBuyUserBought(shopUser.getId(),pid)){

            log.warn("用户:{},购买商品:{},购买数量:{},重复抢购",shopUser.getId(),pid,number);
            return ResultBuildUtil.fail("603","请购失败,重复抢购");
        }

        while (true){
            //死循环,尝试锁库存操作,如果锁库存成功,代表库存锁已被释放,可以继续购买,否则继续等待
            if (!seckillService.checkProdStockLocked(pid)){
                log.info("用户:{},购买商品:{},购买数量:{},锁库存成功",shopUser.getId(),pid,number);
                break;
            }
            log.debug("用户:{},购买商品:{},购买数量:{},锁库存失败",shopUser.getId(),pid,number);
        }

        ShopOrderVO shopOrderVO = new ShopOrderVO();
        shopOrderVO.setId(snowUtil.snowId());
        shopOrderVO.setUserId(shopUser.getId());
        shopOrderVO.setAddressId(addressId);
        shopOrderVO.setShoppingStatus("未支付");
        shopOrderVO.setPostscript(content);
        shopOrderVO.setShoppingFee(10.00);
        log.info("参数" + shopGoodsVO.getIsOnSale());
        log.info("参数" + shopGoodsVO.getSalePrice());
        log.info("参数" + shopGoodsVO.getRetailPrice());
        shopOrderVO.setAddTime(new Date());

        //todo 生成订单详情表,存入数据库,redis
        ShopOrderitemVO shopOrderitemVO = new ShopOrderitemVO();
        shopOrderitemVO.setId(snowUtil.snowId());
        shopOrderitemVO.setBuyingPrice(shopGoodsVO.getIsOnSale() == 1 ? shopGoodsVO.getSalePrice() * number : shopGoodsVO.getRetailPrice() * number);
        shopOrderitemVO.setUserId(shopUser.getId());
        shopOrderitemVO.setNumber(number);
        shopOrderitemVO.setGoodsId(shopGoodsVO.getId());
        shopOrderitemVO.setOrderId(shopOrderVO.getId());
        shopOrderitemVO.setGoodsName(shopGoodsVO.getName());
        shopOrderitemVO.setCategoryId(shopGoodsVO.getCategoryId());

        shopOrderVO.setOrderPrice(shopOrderitemVO.getBuyingPrice()+shopOrderVO.getShoppingFee());

        log.info("输入:" + shopOrderitemVO);
        //把订单详情放入订单中
        shopOrderVO.setShopOrderitemVO(shopOrderitemVO);
        //异步这边存入数据库
        orderService.involveShopOrderServer(shopOrderVO);
        orderService.involveSaveShopOrderitemServer(shopOrderitemVO);

        log.info("shopOrder:"+shopOrderVO);
        //存入redis缓存
        redisUtils.set(shopOrderVO.getId(), shopOrderVO);

        return ResultBuildUtil.success(shopOrderVO.getId());
    }

}
